﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using YAPL.Language.Ast.Utils;

namespace YAPL.Language.Ast {
	public class BinaryExpression : Expression {
		private Expression _left;
		private Expression _right;
		private readonly BinaryOperator _operator; //may be redundant, because expression can be determined by ExpressionType

		public BinaryExpression(ExpressionType nodeType, Type type, Expression left, Expression right, BinaryOperator op)
			: base(nodeType, type) {
			_left = left;
			_right = right;
			_operator = op;
		}

		public BinaryExpression(ExpressionType nodeType, Type type, bool canRead, bool canWrite, Expression left, Expression right, BinaryOperator op)
			: base(nodeType, type, canRead, canWrite) {
			_left = left;
			_right = right;
			_operator = op;
		}

		[Descendant(AstVisit.BeforeCurrent, Priority = 0)]
		public Expression Left {
			get { return _left; }
		}

		[Descendant(AstVisit.BeforeCurrent, Priority = 1)]
		public Expression Right {
			get { return _right; }
		}

		public BinaryOperator Operator {
			get { return _operator; }
		}

		public override bool NodeEquals(Expression other) {
			if (other is BinaryExpression) {
				return _operator.Equals((other as BinaryExpression)._operator);
			}
			return false;
		}

		public override bool RewriteChild(Expression child, Expression newExpression) {
			var rewritten = false;
			if (ReferenceEquals(_left,child)) {
				_left = newExpression;
				rewritten = true;
			}
			if (ReferenceEquals(_right, child)) {
				_right = newExpression;
				rewritten = true;
			}
			return rewritten;
		}
	}
}
